{#if webToPrint}
<div class="toolbar-container">
    <div class="toolbar-caption">Mode</div>

    <div on:click="activate('web')" class="button {mode === 'web' ? 'active' : ''}">Web</div>
    <div on:click="activate('print')" class="button {mode === 'print' ? 'active' : ''}">Print</div>
</div>
{/if}

<div class="toolbar-container" style="display: block">
    <div style="display: flex">
        <div class="toolbar-caption">{ __('chart-size') }</div>

        <div style="padding-top: 4px">
            {#if uiMode === 'print'}
            <input
                autocomplete="off"
                id="resize-w"
                class="input-resize input-large"
                type="number"
                min="0"
                on:change="changed()"
                bind:value="width_txt"
                step="{theUnit.step}"
            />
            ×
            <input
                autocomplete="off"
                id="resize-h"
                class="input-resize input-large"
                type="number"
                min="0"
                on:change="changed()"
                bind:value="height_txt"
                step="{theUnit.step}"
            />
            {:else }
            <input
                id="resize-w"
                class="input-resize input-large"
                type="text"
                on:change="changed()"
                bind:value="width_txt"
            />
            ×
            <input
                id="resize-h"
                class="input-resize input-large"
                type="text"
                on:change="changed()"
                bind:value="height_txt"
            />
            {/if}
        </div>

        {#if uiMode === "print"}
        <div
            class="button"
            on:click="togglePrintOptions()"
            style="min-width: 12px; border-right: none"
        >
            <i class="fa { printExpanded ? 'fa-chevron-up' : 'fa-ellipsis-h' }"></i>
        </div>
        {:else} {#each breakpoints as preset, i}
        <div
            class="
                button
                {width_px
                >=
                preset.minWidth
                &&
                width_px
                <=
                preset.maxWidth
                ?
                'active'
                :
                ''}
            "
            on:click="setWidth(preset.width)"
        >
            <i style="font-size:{preset.iconSize}px" class="fa {preset.icon}"></i>
        </div>
        {/each} {/if}
    </div>

    {#if printExpanded && uiMode === 'print'}
    <div class="toolbar-container options" style="display: block; height: auto; z-index: 1">
        <div style="padding: 12px 8px 0px 8px">
            <!-- prettier-ignore -->
            <RadioControl options="{units}" label="" bind:value="unit" />

            {#if presets.length}
            <div class="control-group" style="margin-bottom: 6px">
                <div class="controls">
                    <select
                        bind:value="preset"
                        on:change="usePreset()"
                        style="max-width: 170px; margin-bottom: 0"
                    >
                        {#each presetOptions as option }
                        <option value="{option.value}">{ option.label }</option>
                        {/each}
                    </select>
                </div>
            </div>
            {/if}
        </div>
        {#if mode === 'print'}
        <div class="button" on:click="reset()">
            <i class="fa fa-undo"></i> &nbsp;Undo print changes
        </div>
        {/if}
    </div>
    {/if}
</div>

<style>
    .toolbar {
        display: flex;
    }

    .toolbar-container > div > *:last-child {
        border-right: none !important;
    }

    .toolbar-container.options {
        margin-left: 0px !important;
        border-right: 1px solid rgba(0, 0, 0, 0.1) !important;
        top: -1px;
        left: -1px;
        width: 100%;
    }
</style>

<script>
    /*  global dw, $ */
    import RadioControl from '@datawrapper/controls/RadioControl.html';
    import httpReq from '@datawrapper/shared/httpReq';
    import { __ } from '@datawrapper/shared/l10n';
    import get from '@datawrapper/shared/get';

    function getUnit(unit, units) {
        for (let i = 0; i < units.length; i++) {
            if (units[i].value === unit) return units[i];
        }
    }
    function getFactor(unit) {
        return unit === 'px' ? 1 : unit === 'mm' ? IN2MM / DPI : 1 / DPI;
    }
    const DPI = 96;
    const IN2MM = 25.4;

    export default {
        components: { RadioControl },
        data() {
            return {
                webToPrint: false,
                mode: '',
                width: 600,
                height: 400,
                width_txt: null,
                height_txt: null,
                unit: 'px',
                visLoading: false,
                units: [
                    { value: 'mm', label: 'mm', step: 1, decimals: 0 },
                    { value: 'in', label: 'in', step: 0.01, decimals: 2 },
                    { value: 'px', label: 'px', step: 1, decimals: 0 }
                ],
                defaultWidths: [320, 400, 600],
                preset: null,
                printExpanded: false
            };
        },
        computed: {
            breakpointWidths({ $teamSettings, defaultWidths }) {
                const widths = $teamSettings.previewWidths;
                if (!widths || !widths.length) return defaultWidths;
                return defaultWidths.map((d, i) =>
                    widths[i] && !isNaN(widths[i]) ? widths[i] : d
                );
            },
            breakpoints({ breakpointWidths }) {
                return [
                    {
                        icon: 'fa-mobile',
                        iconSize: 14,
                        minWidth: 0,
                        maxWidth: breakpointWidths[0],
                        width: breakpointWidths[0]
                    },
                    {
                        icon: 'fa-mobile',
                        iconSize: 17,
                        minWidth: breakpointWidths[0] + 1,
                        maxWidth: breakpointWidths[1],
                        width: breakpointWidths[1]
                    },
                    {
                        icon: 'fa-desktop',
                        iconSize: 14,
                        minWidth: breakpointWidths[1] + 1,
                        maxWidth: Infinity,
                        width: breakpointWidths[2]
                    }
                ];
            },
            width_px({ width, unit, printScale }) {
                return (
                    (width * (unit === 'px' ? 1 : unit === 'mm' ? DPI / IN2MM : DPI)) / printScale
                );
            },
            height_px({ height, unit, printScale }) {
                return (
                    (height * (unit === 'px' ? 1 : unit === 'mm' ? DPI / IN2MM : DPI)) / printScale
                );
            },
            theUnit({ unit, units }) {
                return getUnit(unit, units);
            },
            isPrintTheme({ $themeData }) {
                return get($themeData || {}, 'type', 'web') === 'print';
            },
            uiMode({ mode, isPrintTheme }) {
                return mode === 'print' || isPrintTheme ? 'print' : 'web';
            },
            printScale({ $themeData, uiMode }) {
                return uiMode === 'web' ? 1 : get($themeData || {}, 'export.pdf.scale', 1);
            },
            presets({ $themeData }) {
                return get($themeData || {}, 'export.pdf.presets', []);
            },
            presetOptions({ presets }) {
                if (!presets.length) return [];

                const presetOptions = presets.map((el, i) => {
                    return {
                        value: i,
                        label: el.title
                    };
                });

                presetOptions.unshift({
                    value: '---',
                    label: __('apply-preset')
                });

                return presetOptions;
            },
            defaultPreset({ presets }) {
                for (const preset of presets) {
                    if (preset.default) return preset;
                }
                return {};
            }
        },
        helpers: { __ },
        methods: {
            usePreset() {
                const { preset, presets } = this.get();
                if (preset === '---') return;

                this.set(presets[preset]);
                this.updateSize();
            },
            changed() {
                const app = this;

                clearTimeout(this.debounceUpdateSize);
                this.debounceUpdateSize = setTimeout(function () {
                    app.set({
                        width: app.get().width_txt,
                        height: app.get().height_txt
                    });
                }, 100);
            },
            activate(mode) {
                if (mode === 'web') {
                    if (this.store.getMetadata('custom.webToPrint.webChartId')) {
                        window.location =
                            window.location.protocol +
                            '//' +
                            window.location.host +
                            '/chart/' +
                            this.store.getMetadata('custom.webToPrint.webChartId') +
                            '/visualize';
                    }
                } else if (mode === 'print') {
                    if (this.store.getMetadata('custom.webToPrint.printChartId')) {
                        window.location =
                            window.location.protocol +
                            '//' +
                            window.location.host +
                            '/chart/' +
                            this.store.getMetadata('custom.webToPrint.printChartId') +
                            '/visualize';
                    } else {
                        httpReq
                            .post(`/v3/charts/${dw.backend.currentChart.get().id}/print`)
                            .then(data => {
                                window.location = `${window.location.protocol}//${window.location.host}/chart/${data.id}/visualize`;
                            });
                    }
                }
            },
            setWidth(w) {
                this.set({ width: w });
            },
            setHeight(h) {
                this.set({ height: h });
            },
            togglePrintOptions() {
                this.set({ printExpanded: !this.get().printExpanded });
            },
            reset() {
                if (!window.confirm('Are you sure you want to reset to the web version?')) return;

                httpReq.delete(`/v3/charts/${dw.backend.currentChart.get().id}/print`).then(() => {
                    window.location.reload();
                });
            },
            updateSize() {
                const { width, height, uiMode, unit } = this.get();
                const w = this.get().width_px;
                const h = this.get().height_px;

                const maxW = $('#iframe-wrapper').parent().parent().width() - 22;

                if (uiMode === 'web') {
                    this.store.setMetadata('publish.embed-width', w);
                    this.store.setMetadata('publish.embed-height', h);
                }

                $('#iframe-wrapper').animate(
                    {
                        width: w,
                        height: h,
                        'margin-left': (maxW - w) * 0.5
                    },
                    {
                        duration: uiMode === 'web' ? 200 : 0,
                        step: function () {
                            $(this).css('overflow', 'visible');
                        }
                    }
                );

                $('.visconfig')
                    .css('min-height', +h + 250) // Randomly adds 250px?! TODO: Clarify if that's really necessary.
                    .animate({
                        left: Math.min(0, maxW - w) / 2
                    });

                dw.backend.fire('chart-resize');

                this.set({ width_txt: width, height_txt: height });
                if (this.get().uiMode === 'web') {
                    this.store.setMetadata('publish.embed-width', Math.round(w));
                    this.store.setMetadata('publish.embed-height', Math.round(h));
                } else {
                    this.store.setMetadata('publish.export-pdf.width', width);
                    this.store.setMetadata('publish.export-pdf.height', height);
                    this.store.setMetadata('publish.export-pdf.unit', unit);
                }

                this.measureChartHeight();
            },
            measureChartHeight() {
                clearTimeout(window.measureChartHeightTimeout);

                window.measureChartHeightTimeout = setTimeout(() => {
                    const iframe = $('#iframe-vis').get(0).contentWindow;

                    if (iframe) {
                        var visRendered = iframe.__dw && iframe.__dw.vis.__rendered;
                        var chartBody = iframe.document.querySelector('.dw-chart-body');

                        if (visRendered && chartBody && chartBody.getBoundingClientRect) {
                            var h = chartBody.getBoundingClientRect().height;
                            if (h !== this.store.getMetadata('publish.chart-height')) {
                                this.store.setMetadata('publish.chart-height', h);
                                if (this.store.save) this.store.save();
                            }
                        } else {
                            setTimeout(() => this.measureChartHeight(), 500);
                        }
                    }
                }, 500);
            },
            registerDragAndDropListener() {
                const app = this;
                const iframe = $('#iframe-wrapper').addClass('resizable');
                var startX, startY, startWidth, startHeight;

                iframe.find('.resizer').remove();
                iframe.append('<div class="resizer resizer-both icon-resize-horizontal"></div>');

                $('.resizer', iframe).on('mousedown', dragStart);

                function dragStart(e) {
                    startX = e.clientX;
                    startY = e.clientY;
                    startWidth = iframe.width();
                    startHeight = iframe.height();

                    $(document).on('mousemove', doDrag);
                    $(document).on('mouseup', stopDrag);
                    $('#iframe-vis').addClass('resizing');
                }

                function doDrag(e) {
                    iframe.height(startHeight + e.clientY - startY);
                    iframe.width(startWidth + e.clientX - startX);
                    iframe.css('pointer-events', 'none');
                    e.preventDefault();
                    return false;
                }

                function stopDrag() {
                    $(document).unbind('mousemove', doDrag);
                    $(document).unbind('mouseup', stopDrag);

                    app.set({
                        width: $('#iframe-vis').width(),
                        height: $('#iframe-vis').height()
                    });

                    iframe.css('pointer-events', 'initial');
                    $('#iframe-vis').removeClass('resizing');
                }
            },
            registerTypeListener() {
                const app = this;
                dw.backend.on('type-changed', function (metas) {
                    // switch from fixed to fit
                    if (metas[0].height !== 'fixed' && metas[1].height === 'fixed') {
                        app.setHeight(Math.min(app.get().height_px, 500));
                    }
                });
            },
            registerChartHeightListener() {
                const app = this;

                window.addEventListener('message', function (e) {
                    var message = e.data;

                    if (app.get().loading) return;

                    if (typeof message['datawrapper-height'] !== 'undefined') {
                        var h;

                        for (var chartId in message['datawrapper-height']) {
                            h = message['datawrapper-height'][chartId];
                        }

                        if (
                            !$('#iframe-vis').hasClass('resizing') &&
                            $('#iframe-vis').is(':visible') &&
                            app.get().uiMode !== 'print'
                        ) {
                            app.setHeight(h);
                        }
                    }
                });
            }
        },
        oncreate() {
            this.set({
                mode: this.store.getMetadata('custom.webToPrint.mode', 'web')
            });
        },
        onstate({ changed, current, previous }) {
            const app = this;
            if (!previous) return;

            if (changed.unit && !changed.width && !changed.height) {
                // changed unit, let's recompute
                const scale = current.printScale;
                const factor = getFactor(current.unit);

                this.set({
                    width: +(previous.width_px * factor * scale).toFixed(current.theUnit.decimals),
                    height: +(previous.height_px * factor * scale).toFixed(
                        current.theUnit.decimals
                    ),
                    width_txt: +(previous.width_px * factor).toFixed(current.theUnit.decimals),
                    height_txt: +(previous.height_px * factor).toFixed(current.theUnit.decimals)
                });
            }

            if (changed.mode || changed.isPrintTheme) {
                if (current.uiMode === 'web') {
                    this.set({
                        width: this.store.getMetadata('publish.embed-width'),
                        height: this.store.getMetadata('publish.embed-height'),
                        width_txt: this.store.getMetadata('publish.embed-width'),
                        height_txt: this.store.getMetadata('publish.embed-height'),
                        unit: 'px'
                    });
                    this.registerDragAndDropListener();
                    this.registerTypeListener();
                    this.registerChartHeightListener();

                    app.updateSize();
                } else {
                    const iframe = $('#iframe-wrapper').removeClass('resizable');
                    iframe.find('.resizer').remove();

                    const { width, height, units, defaultPreset } = this.get();
                    const scale = this.get().printScale;
                    const pdf = dw.backend.currentChart.getMetadata('publish.export-pdf', {});
                    const unit = pdf.unit || defaultPreset.unit || 'mm';
                    const decimals = getUnit(unit, units).decimals;
                    const factor = getFactor(unit) * scale;

                    const fallbackWidth =
                        current.mode === 'web'
                            ? (factor * width).toFixed(decimals) /* switched to print theme only */
                            : 80; /* switched mode (legacy behaviour) */

                    const fallbackHeight =
                        current.mode === 'web' ? (factor * height).toFixed(decimals) : 120;

                    const w = pdf.width || defaultPreset.width || fallbackWidth;
                    const h = pdf.height || defaultPreset.height || fallbackHeight;

                    this.set({
                        width: w,
                        height: h,
                        width_txt: w,
                        height_txt: h,
                        unit
                    });
                    app.updateSize();
                }
            }

            if ((changed.width_px || changed.height_px) && current.width_px && current.height_px) {
                app.updateSize();
            }
        }
    };
</script>
